package com.fleapx.spring.hook.springhooktest.importBeanDefinitionRegistrar;

import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.annotation.ClassPathBeanDefinitionScanner;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.core.type.filter.AssignableTypeFilter;
import org.springframework.core.type.filter.TypeFilter;

import java.util.Map;

public class ImportBeanDefinitionRegistrarTest implements ImportBeanDefinitionRegistrar {
    /**
     * 通过该接口动态注册bean，需要指定扫描的路径，以及扫描的指定类型或者排除指定类型，
     * 必须依赖于@Import注解动态加载，@Component、@Service注解都是基于这个原理实现的
     * @param importingClassMetadata
     * @param registry
     */
   public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
       //扫描注解
       Map<String, Object> annotationAttributes = importingClassMetadata.getAnnotationAttributes(ComponentScan.class.getName());
       String[] basePackages = (String[]) annotationAttributes.get("basePackages");
       //扫描类
       //ClassPathBeanDefinitionScannerkeyi 可以看成是一个工具类，其底层利用了registry.registerBeanDefinition方法注册BeanDefinition
       ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(registry, false);
       TypeFilter helloServiceFilter = new AssignableTypeFilter(HelloService.class);
       scanner.addIncludeFilter(helloServiceFilter);//这里的TypeFilter是接口，支持注解类型的，也支持指定类的
       scanner.scan(basePackages);//扫描的路径
    }
}
